/*
 *    Copyright (c) 2018-2025, boss All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the boss developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: boss
 */
package com.hopes.bizz.risk.control.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hopes.bizz.risk.control.bo.*;
import com.hopes.bizz.risk.control.entity.RiskOperationalEvaluationDetailEntity;
import com.hopes.bizz.risk.control.entity.RiskOperationalEvaluationEntity;
import com.hopes.bizz.risk.control.evaluate.RiskCalculateService;
import com.hopes.bizz.risk.control.mapper.RiskOperationalEvaluationMapper;
import com.hopes.bizz.risk.control.service.RiskOperationalEvaluationDetailService;
import com.hopes.bizz.risk.control.service.RiskOperationalEvaluationService;
import com.hopes.bizz.risk.setting.entity.RiskEffectEvaluationConfigEntity;
import com.hopes.bizz.risk.setting.service.RiskEffectEvaluationConfigService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

/**
 * 机制运行评估记录
 *
 * @author pig
 * @date 2023-07-18 16:14:05
 */
@Service
public class RiskOperationalEvaluationServiceImpl extends ServiceImpl<RiskOperationalEvaluationMapper, RiskOperationalEvaluationEntity> implements RiskOperationalEvaluationService {

    @Resource
    private RiskOperationalEvaluationDetailService riskOperationalEvaluationDetailService;

    @Resource
    private RiskCalculateService riskCalculateService;

    @Resource
    private RiskEffectEvaluationConfigService riskEffectEvaluationConfigService;

    @Override
    public void saveCalculateStatistics() {
        // 上周一 到 上周日
        Date lastWeekDate = DateUtil.offsetWeek(new Date(), -1);
        Date startTime = DateUtil.beginOfWeek(lastWeekDate);
        // 数据库入库的时候会有500毫秒的进位
        Date endTime = DateUtil.endOfWeek(lastWeekDate).offset(DateField.MILLISECOND,-999);
        saveCalculateStatistics(startTime, endTime);
    }

    @Override
    public void saveCalculateStatistics(Date startTime, Date endTime) {
        // 构建得、扣分项
        RiskEffectEvaluationConfigEntity riskEffectEvaluationConfig = riskEffectEvaluationConfigService.queryForOne();
        RiskEffectEvaluationScore riskEffectEvaluationScore = new RiskEffectEvaluationScore(riskEffectEvaluationConfig);
        RiskEvaluateBo riskEvaluateBo = new RiskEvaluateBo(startTime, endTime, riskEffectEvaluationScore);
        // 计算A 、B、否决因子得分
        RiskCheckTaskScore riskCheckTaskScore = riskCalculateService.calculateRiskCheckTaskScore(riskEvaluateBo);
        HidTaskScore hidTaskScore = riskCalculateService.calculateHidTaskScore(riskEvaluateBo);
        NegatedItem negatedItem = riskCalculateService.calculateRejectScore(riskEvaluateBo);
        // 查询数据是否存在
        int year = DateUtil.year(startTime);
        int week = DateUtil.weekOfYear(startTime);
        Long riskOperationalEvaluationId = this.baseMapper.selectByWeekAndYear(week, year);

        RiskOperationalEvaluationEntity riskOperationalEvaluation = new RiskOperationalEvaluationEntity();
        riskOperationalEvaluation.setTotalPoints(NumberUtil.round((riskCheckTaskScore.getScore() + hidTaskScore.getScore()) * (negatedItem.getScore().equals(Boolean.FALSE) ? 0 : 1), 2).doubleValue());
        riskOperationalEvaluation.setStartTime(startTime);
        riskOperationalEvaluation.setEndTime(endTime);
        riskOperationalEvaluation.setWeek(week);
        riskOperationalEvaluation.setYear(year);
        riskOperationalEvaluation.setRiskTaskScore(riskCheckTaskScore.getScore());
        riskOperationalEvaluation.setHidTaskScore(hidTaskScore.getScore());
        riskOperationalEvaluation.setNegatedItem(negatedItem.getScore());
        // 存在更新数据
        if (riskOperationalEvaluationId != null){
            riskOperationalEvaluation.setId(riskOperationalEvaluationId);
            this.updateById(riskOperationalEvaluation);
        }else {
            // 保存
            this.save(riskOperationalEvaluation);
        }
        // 保存记录详情
        RiskOperationalEvaluationDetailEntity detail = new RiskOperationalEvaluationDetailEntity();
        detail.setRiskOperationalEvaluationId(riskOperationalEvaluation.getId());
        detail.setTotalPoints(riskOperationalEvaluation.getTotalPoints());
        detail.setHidTaskScore(hidTaskScore.getScore());
        detail.setRiskTaskScore(riskCheckTaskScore.getScore());
        BeanUtil.copyProperties(riskCheckTaskScore, detail);
        BeanUtil.copyProperties(hidTaskScore, detail);
        BeanUtil.copyProperties(negatedItem, detail);
        riskOperationalEvaluationDetailService.save(detail);
    }
}
